<template>
  <div>
    <el-dialog
      title="模型测试"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      width="50%"
      @close="cancel"
    >
      <div>
        <el-tabs v-model="activeName">
          <el-tab-pane label="推荐资源" name="first">
            <image-list @click="handleClickImg"/>
          </el-tab-pane>
          <el-tab-pane label="自定义资源" name="second">
            <p class="tip_message">tips:可自定义上传猫咪或者狗狗的图片以供模型区分(上传其他类型图片可能会被误识别)</p>

            <div class="upload_img">
              <upload-img @change="handleChangeUpload"/>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
      <span slot="footer" class="dialog-footer">
                <el-button @click="cancel" size="small">取 消</el-button>
            </span>
    </el-dialog>
    <test-result-dialog
      v-if="resultVisible"
      v-bind="{
      prediction,
      img: imgSrc,
    }"
      @cancel="resultVisible = false"
    />
  </div>
</template>

<script>
import ImageList from '@/views/demo/page1/components/image-list.vue'
import { preprocessImage } from '@/views/demo/page1/utils/formatImages'
import TestResultDialog from '@/views/demo/page1/dialog/test-result-dialog.vue'
import UploadImg from '@/views/demo/page1/components/upload-img.vue'

export default {
  filters: {},
  components: {
    ImageList,
    TestResultDialog,
    UploadImg
  },
  props: ['model', 'tf'],
  watch: {},
  computed: {},
  data () {
    return {
      activeName: 'first',
      prediction: {
        label: '猫',
        confidence: 0
      },

      resultVisible: false,
      imgSrc: null,
      dialogVisible: true,
      buttonLoading: false
    }
  },
  created () {
  },
  mounted () {
  },
  methods: {
    async handleClickImg (imgInfo) {
      const {
        category,
        index,
        src
      } = imgInfo
      this.imgSrc = src
      try {
        const imgPath = require(`@/views/demo/page1/assets/image/${category}/${category}.${index}.jpg`)
        const image = await this.loadImage(imgPath)
        console.log('image', image)
        this.predict(image)
      } catch (e) {
        console.log(e)
      }
    },
    predict (imgData) {
      if (!this.model) return
      const input = imgData.tensor.expandDims(0) // 添加批次维度
      const prediction = this.model.predict(input)
      const probabilities = Array.from(prediction.dataSync())
      this.prediction = {
        label: probabilities[0] > probabilities[1] ? '猫' : '狗',
        confidence: Math.max(...probabilities) * 100
      }
      console.log('预测结果:', this.prediction)
      this.tf.dispose([input, prediction])
      this.resultVisible = true
    },
    async loadImage (imgPath) {
      const img = new Image()
      img.src = imgPath.default || imgPath
      await new Promise((resolve, reject) => {
        img.onload = () => resolve(img)
        img.onerror = (err) => {
          console.error(`图片加载失败: ${imgPath}`)
          reject(err)
        }
      })
      return {
        path: imgPath,
        element: img,
        tensor: this.tf.browser.fromPixels(preprocessImage(img)).div(255) // 归一化
      }
    },
    async handleChangeUpload (imgPath) {
      const image = await this.loadImage(imgPath)
      this.imgSrc = imgPath
      console.log('image', image)
      this.predict(image)
    },
    cancel () {
      this.dialogVisible = false
      setTimeout(() => {
        this.$emit('cancel')
      }, 500)
    }
  }
}
</script>

<style lang="scss" scoped>
.upload_img {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tip_message {
  font-size: 12px;
  color: #909399;
}
</style>
